﻿using TimeMachine.Engine.Storing;
using TimeMachine.Engine.Vcs;

namespace TimeMachine.Engine.Metrics.Impl
{
	[MetricDescriptor("LOC")]
	public class LocMetric : BaseMetric
	{
		private readonly IMetricsStorage metricValues;
		private readonly IChangesProcessor changesProcessor;
		private readonly ISourcesSettings sourcesSettings;

		public LocMetric(IMetricsStorage metricValues, IChangesProcessor changesProcessor,
		                 ISourcesSettings sourcesSettings)
		{
			this.metricValues = metricValues;
			this.changesProcessor = changesProcessor;
			this.sourcesSettings = sourcesSettings;
		}

		public override MetricValue Calculate(int rev)
		{
			MetricValue prevCommit = metricValues.FindPrevValue(Desc.MetricId, rev);
			double loc = prevCommit == null ? 0 : prevCommit.Value;
			changesProcessor.ProcessChanges(
				rev,
				new ProcessChangesParams
					{
						OnNextFile = 
							filename => sourcesSettings.IsSourceFile(filename) && sourcesSettings.IsInTrunk(filename),
						OnNextChange = 
							change => loc += ((change is LineAddedInfo) ? 1 : 0) + ((change is LineRemovedInfo) ? -1 : 0)
					}
				);
			return new MetricValue(rev, Desc.MetricId, loc);
		}

		public override IAggregator CreateAggregator()
		{
			return new LastValue();
		}
	}

	public class LastValue : IAggregator
	{
		public double lastValue;

		public void StartNewPeriod()
		{
		}

		public void Aggregate(double value)
		{
			lastValue = value;
		}

		public double GetResult(double aggregationPeriodInDays)
		{
			return lastValue;
		}
	}
}